From 496d4573efbbaa3ae88556bb1695b7b1ce7c0bf5 Mon Sep 17 00:00:00 2001 From: "iap10@freefall.cl.cam.ac.uk" Date: Thu, 24 Mar 2005 03:10:42 +0000 Subject: [PATCH] bitkeeper revision 1.1236.42.1 (42422fb2SvqEyBwXAZf3p2BJS-gfBA) If Xen is told to use a serial console via a com1= or com2= directive on the Xen command line, it now hides that particular UART from dom0. This means that it's now safe to enable the 8250 driver in the Linux config. If Xen has been told to use com1, the dom0 linux kernel will not see /dev/ttyS0, but will see ttyS1,S2 etc if they are present, enabling them to be used for mice, modems, printers etc. Unfortunately, the 8250 driver will register itself for a ttyS even if that particular UART isn't present. This is really annoying, as it prevents the 'xencons' driver registering itself as ttyS0 even though the 8250 won't see ttyS0 as present if Xen is using com1. This prevents us from enabling 8250 in the default kernel config, as it will change current behaviour. If you want to use 8250 and xencons, the trick is to tell xencons to grab a high numbered ttyS port that the 8250 driver will have left alone. For example, put "xencons=ttyS31" on the Linux command line. You'll then be able to edit /etc/inittab to add an entry for a getty on ttyS31 if you want to be able to log in on the serial console that is being shared with Xen. If anyone knows a way of cleanly kicking the 8250 driver off a particular char minor then please let me know! --- .rootkeys | 1 + .../drivers/xen/console/console.c | 58 ++++++++++++++----- xen/arch/x86/setup.c | 4 ++ xen/common/dom0_ops.c | 2 +- xen/common/physdev.c | 14 +++++ xen/drivers/char/serial.c | 16 +++++ xen/include/xen/physdev.h | 19 ++++++ xen/include/xen/serial.h | 2 + 8 files changed, 100 insertions(+), 16 deletions(-) create mode 100644 xen/include/xen/physdev.h diff --git a/.rootkeys b/.rootkeys index 64f3c714b0..e05072a017 100644 --- a/.rootkeys +++ b/.rootkeys @@ -1317,6 +1317,7 @@ 3ddb79c0MOVXq8qZDQRGb6z64_xAwg xen/include/xen/pci_ids.h 3e54c38dlSCVdyVM4PKcrSfzLLxWUQ xen/include/xen/perfc.h 3e54c38de9SUSYSAwxDf_DwkpAnQFA xen/include/xen/perfc_defn.h +42422fb0FVX-TJkSvAXnbfwMf19XFA xen/include/xen/physdev.h 3ddb79c04nQVR3EYM5L4zxDV_MCo1g xen/include/xen/prefetch.h 3e4540ccU1sgCx8seIMGlahmMfv7yQ xen/include/xen/reboot.h 40589969nPq3DMzv24RDb5LXE9brHw xen/include/xen/sched-if.h diff --git a/linux-2.6.11-xen-sparse/drivers/xen/console/console.c b/linux-2.6.11-xen-sparse/drivers/xen/console/console.c index fb276216be..d0948132d7 100644 --- a/linux-2.6.11-xen-sparse/drivers/xen/console/console.c +++ b/linux-2.6.11-xen-sparse/drivers/xen/console/console.c @@ -63,15 +63,33 @@ * warnings from standard distro startup scripts. */ static enum { XC_OFF, XC_DEFAULT, XC_TTY, XC_SERIAL } xc_mode = XC_DEFAULT; +static int xc_num = -1; static int __init xencons_setup(char *str) { - if ( !strcmp(str, "tty") ) - xc_mode = XC_TTY; - else if ( !strcmp(str, "ttyS") ) + char *q; + int n; + + if ( !strncmp(str, "ttyS", 4) ) xc_mode = XC_SERIAL; - else if ( !strcmp(str, "off") ) + else if ( !strncmp(str, "tty", 3) ) + xc_mode = XC_TTY; + else if ( !strncmp(str, "off", 3) ) xc_mode = XC_OFF; + + switch (xc_mode) + { + case XC_SERIAL: + n = simple_strtol( str+4, &q, 10 ); + if ( q>str+4 ) xc_num = n; + break; + + case XC_TTY: + n = simple_strtol( str+3, &q, 10 ); + if ( q>str+3 ) xc_num = n; + break; + } +printk("xc_num = %d\n",xc_num); return 1; } __setup("xencons=", xencons_setup); @@ -187,15 +205,24 @@ void xen_console_init(void) kcons_info.write = kcons_write; } - if ( xc_mode == XC_OFF ) - return __RETCODE; - - if ( xc_mode == XC_SERIAL ) + switch ( xc_mode ) + { + case XC_SERIAL: strcpy(kcons_info.name, "ttyS"); - else + if ( xc_num == -1 ) xc_num = 0; + break; + + case XC_TTY: strcpy(kcons_info.name, "tty"); + if ( xc_num == -1 ) xc_num = 1; + break; + + default: + return __RETCODE; + } register_console(&kcons_info); + return __RETCODE; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) @@ -705,14 +732,14 @@ static int __init xencons_init(void) if ( xc_mode == XC_SERIAL ) { DRV(xencons_driver)->name = "ttyS"; - DRV(xencons_driver)->minor_start = 64; - DRV(xencons_driver)->name_base = 0; + DRV(xencons_driver)->minor_start = 64 + xc_num; + DRV(xencons_driver)->name_base = 0 + xc_num; } else { DRV(xencons_driver)->name = "tty"; - DRV(xencons_driver)->minor_start = 1; - DRV(xencons_driver)->name_base = 1; + DRV(xencons_driver)->minor_start = xc_num; + DRV(xencons_driver)->name_base = xc_num; } #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) @@ -759,8 +786,9 @@ static int __init xencons_init(void) (void)ctrl_if_register_receiver(CMSG_CONSOLE, xencons_rx, 0); } - printk("Xen virtual console successfully installed as %s\n", - DRV(xencons_driver)->name); + printk("Xen virtual console successfully installed as %s%d\n", + DRV(xencons_driver)->name, + DRV(xencons_driver)->name_base ); return 0; } diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index 7ae035187d..73f48150ef 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -617,6 +618,9 @@ void __init __start_xen(multiboot_info_t *mbi) /* Give up the VGA console if DOM0 is configured to grab it. */ console_endboot(cmdline && strstr(cmdline, "tty0")); + /* Hide UART from DOM0 if we're using it */ + serial_endboot(); + domain_unpause_by_systemcontroller(current->domain); domain_unpause_by_systemcontroller(dom0); startup_cpu_idle_loop(); diff --git a/xen/common/dom0_ops.c b/xen/common/dom0_ops.c index 75547d989c..d20a851e5d 100644 --- a/xen/common/dom0_ops.c +++ b/xen/common/dom0_ops.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include @@ -402,7 +403,6 @@ long do_dom0_op(dom0_op_t *u_dom0_op) case DOM0_PCIDEV_ACCESS: { - extern int physdev_pci_access_modify(domid_t, int, int, int, int); ret = physdev_pci_access_modify(op->u.pcidev_access.domain, op->u.pcidev_access.bus, op->u.pcidev_access.dev, diff --git a/xen/common/physdev.c b/xen/common/physdev.c index 652c9c2afe..83dce4d4a7 100644 --- a/xen/common/physdev.c +++ b/xen/common/physdev.c @@ -105,6 +105,20 @@ static int setup_ioport_memory_access(struct domain *d, struct pci_dev *pdev) return 0; } +void physdev_modify_ioport_access_range( struct domain *d, int enable, + int port, int num ) +{ + int i; + ASSERT( d->arch.iobmp_mask ); + for ( i = port; i < port+num; i++ ) + { + if(enable) + clear_bit(i, d->arch.iobmp_mask); + else + set_bit(i, d->arch.iobmp_mask); + } +} + /* Add a device to a per-domain device-access list. */ static int add_dev_to_task(struct domain *d, struct pci_dev *dev, int acc) { diff --git a/xen/drivers/char/serial.c b/xen/drivers/char/serial.c index 99e1b1a42e..e9eb6eff2f 100644 --- a/xen/drivers/char/serial.c +++ b/xen/drivers/char/serial.c @@ -15,6 +15,7 @@ #include #include #include +#include #include /* Config serial port with a string ,DPS,,. */ @@ -479,6 +480,21 @@ void serial_force_unlock(int handle) uart->lock = SPIN_LOCK_UNLOCKED; } +void serial_endboot() +{ + int i; + + for (i=0;i + +void physdev_modify_ioport_access_range( struct domain *d, int enable, + int port, int num ); +void physdev_destroy_state(struct domain *d); +int physdev_pci_access_modify(domid_t dom, int bus, int dev, int func, + int enable); +int domain_iomem_in_pfn(struct domain *p, unsigned long pfn); +long do_physdev_op(physdev_op_t *uop); +void physdev_init_dom0(struct domain *d); + +#endif /* __XEN_PHYSDEV_H__ */ diff --git a/xen/include/xen/serial.h b/xen/include/xen/serial.h index 60fd64186d..4d33ddb17b 100644 --- a/xen/include/xen/serial.h +++ b/xen/include/xen/serial.h @@ -50,6 +50,8 @@ unsigned char irq_serial_getc(int handle); void serial_force_unlock(int handle); +void serial_endboot(void); + #endif /* __XEN_SERIAL_H__ */ /* -- 2.30.2